/**
 * 
 */

/*
 * jQuery.sap.declare("customertable.NCTable") ;
 * jQuery.sap.require("sap.ui.table.Table") ;
 * jQuery.sap.require("sap.ui.table.TableRenderer") ;
 */

sap.ui.define([
    "sap/ui/table/Table", "sap/ui/commons/Label"
], function() {

    "use strict";

    return sap.ui.table.Table.extend("sap.lx.nba.UserController", {

        /***
         * define meta data 
         * @properties :
         *          isdisplayMode: set the default mode is display or eidt
         * @event : 
         *          onSave: not use
         */
        metadata: {
            properties: {
                "isDisplayMode": {
                    type: "boolean",
                    defaultValue: true
                }
            },
            events: {
                "onSave": {}
            }
        },

        /***
         * initial the control by sap core automatic.
         * define the "_bReady" it will be used to judge whether is first to initModel and initSetting.
         * initial most objects what this control need.
         * like constants,columns,row's template include display and edit mode , tool bar too.
         * they will user to build the user control to show users' information.
         */
        init: function() {
            sap.ui.table.Table.prototype.init.apply(this, arguments);
            this._bReady = false;
            this._initConstant();
            this._initColumn();
            this._initDisplayTemplate();
            this._initEditTemplate();
            this._initToolbar();
        },

        /***
         * this function will be call before render the control by sap core automatic.
         * if the first call this function it will initial model and some setting of this control.
         * because the properties of metadata can't use in init function.
         * so when user define some special settings they can set in this function.
         */
        onBeforeRendering: function() {
            if (this._bReady === false) {
                this._initModel();
                this._initTableSetting();
                this._bReady = true;
            }
            sap.ui.table.Table.prototype.onBeforeRendering.apply(this, arguments);
        },

        /***
         * use to change mode to display it can be used out this function
         * @public 
         */
        toDisplay: function() {
            this._Display();
        },

        /***
         * user to change mode to edit it can be used out this function 
         * @public
         */
        toEdit: function() {
            this._Edit();
        },

        /***
         * get the modified data in edit mode include add,delete and update data it should call when change to display mode.
         * it use out this function.
         * it not finish version
         * @return this._oModifiedData 
         * a data include add,less,updata data array.
         * it look like this 
         * "{"add":[{"id":-2,"role":"AppAdmin","validFrom":"07/01/2016","validTo":"12/31/9999"}],"less":[{"id":1,"role":"AppAdmin","name":null,"email":null,"validFrom":"07/01/2016","validTo":"12/31/9999","status":"CLOSED","firstName":null,"lastName":null},{"id":2,"role":"AppAdmin","name":null,"email":null,"validFrom":"07/01/2016","validTo":"12/31/9999","status":"CLOSED","firstName":null,"lastName":null}],"update":[{"id":0,"role":"AppAdmin","name":null,"email":null,"validFrom":"07/01/2016","validTo":"12/31/9999","status":null,"firstName":null,"lastName":null},{"id":3,"role":"AppAdmin","name":null,"email":null,"validFrom":"07/01/2016","validTo":"12/31/9999","status":null,"firstName":null,"lastName":null},{"id":4,"role":"AppAdmin","name":null,"email":null,"validFrom":"07/01/2016","validTo":"12/31/9999","status":"CLOSED","firstName":null,"lastName":null}]}"
         */
        getModifiedData: function() {
            var data = this.getModel().getData();
            var items = data['data'];
            var add = [];
            var less = [];
            var update = [];
            for (var i = 0; i < items.length; i++) {
                delete items[i].selected;
                if (items[i].id === -1) {
                    items[i].id = -2;
                    add.push(items[i]);
                } else {
                    update.push(items[i]);
                }
            }
            for (var i = 0; i < this._oModifiedData.update.length; i++) {
                var exist = false;
                for (var j = 0; j < update.length; j++) {
                    if (this._oModifiedData.update[i].id === update[j].id) {
                        exist = true;
                        break;
                    }
                }
                if (!exist) {
                    delete this._oModifiedData.update[i].selected;
                    less.push(this._oModifiedData.update[i]);
                }
            }
            this._oModifiedData.add = add;
            this._oModifiedData.less = less;
            this._oModifiedData.update = update;
            return this._oModifiedData;
        },

        /***
         * refresh model get the model form backend again
         */
        refresh: function() {
            this._initModel();
        },

        /***
         * define constants like columns name.
         * it will be instead by i18n
         */
        _initConstant: function() {
            // define the constant
            this._sAction = "Action";
            this._sUser = "User";
            this._sEmail = "Email";
            this._sRole = "Role";
            this._sUserRole = "Admin";
            this._sUserName = "Zhang,Abel";
        },

        /***
         * initial model from backend  
         */
        _initModel: function() {
            /* var jsData = new sap.ui.model.json.JSONModel({
                 data: [
                     {
                         email: "lx@sap.com",
                         password: "dfadf",
                         name: "lx",
                         id: 1,
                         role: "AppAdmin",
                         status: "OPEN",
                         validFrom: "dd/mm/yyyy"
                     }, {
                         email: "lx@sap.com",
                         password: "dfadf",
                         id: 2,
                         role: "MRSUser",
                         status: "CLOSED",
                         validFrom: "06/07/2016"
                     }, {
                         email: "lx@sap.com",
                         password: "dfadf",
                         status: "new",
                         id: 3,
                         role: "SubcontractorUser"
                     }
                 ]

             });*/

            var model = new sap.ui.model.json.JSONModel();

            model.loadData("../user/top/get", null, false);

            this.setModel(model);
            this._oModifiedData = {
                add: [],
                less: [],
                update: []
            };
            var items = model.getData().data;
            for (var i = 0; i < items.length; i++) {
                items[i].selected = false;
                this._oModifiedData.update.push(items[i]);
            }
        },

        /***
         * create all columns let them can user when need
         */
        _initColumn: function() {
            // define some common columns
            this._oActionColumn = this._createCommonColumn("Action");
            this._oUserColumn = this._createCommonColumn("User");
            this._oEmailColumn = this._createCommonColumn("Email");
            this._oRoleColumn = this._createCommonColumn("Role");
            this._oValidFromColumn = this._createCommonColumn("Valid From");
            this._oValidToColumn = this._createCommonColumn("Valid To");
            this._oStatusColumn = this._createCommonColumn("Status");
            this._oFirstNameColumn = this._createCommonColumn("First Name");
            this._oLastNameColumn = this._createCommonColumn("Last Name");

            this._oActionColumn.setHAlign(sap.ui.core.HorizontalAlign.Center);
            this._oActionColumn.setWidth("5rem");
            this._oStatusColumn.setHAlign(sap.ui.core.HorizontalAlign.Center);
            this._oStatusColumn.setWidth("5rem");
        },

        /***
         * define display mode row template.
         * they will be add in columns which they are belong 
         */
        _initDisplayTemplate: function() {

            var that = this;

            this._oActionDisplayTemplate = new sap.m.Button({
                icon: "sap-icon://email",
                press: function(oEvent) {
                    that._sendEmail(oEvent, that);
                }
            });
            this._oActionDisplayTemplate.setType(sap.m.ButtonType.Emphasized);

            this._oUserDisplayTemplate = new sap.m.ObjectIdentifier({
                title: that._sUserRole,
                text: that._sUserName
            });

            this._oEmailDisplayTemplate = this._createCommonText("email");

            this._oRoleDisplayTemplate = new sap.m.Text({
                text: {
                    parts: [
                        {
                            path: "role"
                        }
                    ],
                    formatter: function(status) {
                        switch (status) {
                            case "AppAdmin":
                                return "App Admin";
                            case "CompanyAdmin":
                                return "Company Admin";
                            case "MRSUser":
                                return "MRS User";
                            case "SubcontractorUser":
                                return "Subcontractor User";
                        }
                    }
                }
            });

            this._oValidFromDisplayTemplate = this._createCommonText("validFrom");

            this._oValidToDisplayTemplate = this._createCommonText("validTo");

            this._oStatusDisplayTemplate = new sap.m.Button({
                icon: {
                    parts: [
                        {
                            path: "status"
                        }
                    ],
                    formatter: function(status) {
                        switch (status) {
                            case "OPEN":
                                return "sap-icon://unlocked";
                            case "CLOSED":
                                return "sap-icon://locked";
                            case "PLAN":
                                return "sap-icon://future";
                            case "FINISHED":
                                return "sap-icon://sys-enter";
                            case "CANCEL":
                                return "sap-icon://sys-cancel";
                            default:
                                return "sap-icon://question-mark";
                        }
                    }
                }
            });
            this._oStatusDisplayTemplate.setEnabled(false);
            this._oStatusDisplayTemplate.setType(sap.m.ButtonType.Transparent);
        },

        /***
         * define display mode row template.
         * they will be add in columns which they are belong 
         */
        _initEditTemplate: function() {
            var that = this;

            this._oUserEditTemplate = this._createCommonInput("user");
            this._oEmailEditTemplate = this._createCommonInput("email");
            this._oRoleEditTemplate = new sap.m.Select({
                items: [
                    new sap.ui.core.Item({
                        key: "AppAdmin",
                        text: "App Admin"
                    }), new sap.ui.core.Item({
                        key: "CompanyAdmin",
                        text: "Company Admin"
                    }), new sap.ui.core.Item({
                        key: "MRSUser",
                        text: "MRS User"
                    }), new sap.ui.core.Item({
                        key: "SubcontractorUser",
                        text: "Subcontractor User"
                    })
                ],
                selectedKey: "{role}",
                change: that._roleSelected,
                width: "100%"
            });
            this._oValidFromEditTemplate = new sap.m.DatePicker({
                displayFormat: "MM/dd/yyyy",
                valueFormat: "MM/dd/yyyy",
                value: "{validFrom}"
            });
            this._oValidToEditTemplate = new sap.m.DatePicker({
                displayFormat: "MM/dd/yyyy",
                valueFormat: "MM/dd/yyyy",
                value: "{validTo}"
            });
            this._oFirstNameEditTemplate = this._createCommonInput("firstName");
            this._oLastNameEditTemplate = this._createCommonInput("lastName");
            this._oStatusEditTemplate = new sap.m.Button({
                icon: {
                    parts: [
                        {
                            path: "status"
                        }
                    ],
                    formatter: function(status) {
                        switch (status) {
                            case "OPEN":
                                return "sap-icon://unlocked";
                            case "CLOSED":
                                return "sap-icon://locked";
                            case "PLAN":
                                return "sap-icon://future";
                            case "FINISHED":
                                return "sap-icon://sys-enter";
                            case "CANCEL":
                                return "sap-icon://sys-cancel";
                            default:
                                return "sap-icon://question-mark";
                        }
                    }
                }
            });
            this._oStatusEditTemplate.setEnabled(false);
            this._oStatusEditTemplate.setType(sap.m.ButtonType.Transparent);
        },

        /***
         * define tool bar of this control 
         */
        _initToolbar: function() {
            this._oAddButton = this._createCommonButton("add", this._addUser);
            this._oLessButton = this._createCommonButton("less", this._lessUser);
            this._oLockedButton = this._createCommonButton("locked", this._lockUser);
            this._oUnLockedButton = this._createCommonButton("unlocked", this._unLockUser);
            this._oAddButton.setEnabled(true);

            this._oToolbar = new sap.ui.commons.Toolbar();
            this._oToolbar.addItem(this._oAddButton);
            this._oToolbar.addItem(this._oLessButton);
            this._oToolbar.addItem(this._oLockedButton);
            this._oToolbar.addItem(this._oUnLockedButton);

        },

        /***
         * set this control mode , bind the data for showing rows and attach the selection event
         */
        _initTableSetting: function() {
            if (this.getIsDisplayMode()) {
                this._Display();
            } else {
                this._Edit();
            }
            this.bindRows("/data");
            this.attachRowSelectionChange(null, this._selectedItem);
        },

        /***
         * private function change mode to display.
         * remove all columns before used and add display mode's columns .
         * set template of each display mode's column.
         * hide the tool bar.
         * set selection mode to single mode.
         * not fix column.
         */
        _Display: function() {
            this._oActionColumn.setTemplate(this._oActionDisplayTemplate);
            this._oUserColumn.setTemplate(this._oUserDisplayTemplate);
            this._oEmailColumn.setTemplate(this._oEmailDisplayTemplate);
            this._oRoleColumn.setTemplate(this._oRoleDisplayTemplate);
            this._oValidFromColumn.setTemplate(this._oValidFromDisplayTemplate);
            this._oValidToColumn.setTemplate(this._oValidToDisplayTemplate);
            this._oStatusColumn.setTemplate(this._oStatusDisplayTemplate);

            this.removeAllColumns();
            this.addColumn(this._oActionColumn);
            this.addColumn(this._oUserColumn);
            this.addColumn(this._oEmailColumn);
            this.addColumn(this._oRoleColumn);
            this.addColumn(this._oValidFromColumn);
            this.addColumn(this._oValidToColumn);
            this.addColumn(this._oStatusColumn);
            this.setToolbar(null);
            this.setSelectionMode(sap.ui.commons.TreeSelectionMode.Single);
            this.setFixedColumnCount(0);
        },

        /***
         * private function change mode to edit.
         * remove all columns before used and add edit mode's columns .
         * set template of each edit mode's column.
         * show the tool bar.
         * set selection mode to multi mode.
         * fix user column.
         */
        _Edit: function() {
            this._oUserColumn.setTemplate(this._oUserEditTemplate);
            this._oEmailColumn.setTemplate(this._oEmailEditTemplate);
            this._oRoleColumn.setTemplate(this._oRoleEditTemplate);
            this._oValidFromColumn.setTemplate(this._oValidFromEditTemplate);
            this._oValidToColumn.setTemplate(this._oValidToEditTemplate);
            this._oFirstNameColumn.setTemplate(this._oFirstNameEditTemplate);
            this._oLastNameColumn.setTemplate(this._oLastNameEditTemplate);
            this._oStatusColumn.setTemplate(this._oStatusEditTemplate);

            this.removeAllColumns();
            this.addColumn(this._oUserColumn);
            this.addColumn(this._oEmailColumn);
            this.addColumn(this._oRoleColumn);
            this.addColumn(this._oValidFromColumn);
            this.addColumn(this._oValidToColumn);
            this.addColumn(this._oFirstNameColumn);
            this.addColumn(this._oLastNameColumn);
            this.addColumn(this._oStatusColumn);
            this.setToolbar(this._oToolbar);
            this.setSelectionMode(sap.ui.table.SelectionMode.MultiToggle);
            this.setFixedColumnCount(1);
            this._enabledToolbarButton(false);
        },

        /***
         * create a column , all column create by this function.
         * be sure that all column look like same. 
         * @param name String 
         * the name of this column it will show in view.
         * @return sap.ui.table.Column
         */
        _createCommonColumn: function(name) {
            return new sap.ui.table.Column({
                label: new sap.ui.commons.Label({
                    text: name
                }),
                autoResizable: true,
                width: "15rem"
            })
        },

        /***
         * create a text , most display row use this text to show data.
         * @param name String
         * the name of this text and it will bind data by this name.
         * @return sap.m.Text
         */
        _createCommonText: function(name) {
            var model = "{" + name + "}";
            return new sap.m.Text({
                text: model,
                width: "100%"
            });
        },

        /***
         * create a input , most edit row use this input to update data.
         * @param name String
         * the value of this input and it will bind the data by this name.
         * when the input value change the data will change tooo.
         * @return sap.m.Input
         */
        _createCommonInput: function(name) {
            var model = "{" + name + "}";
            return new sap.m.Input({
                value: model,
                width: "100%"
            });
        },

        /***
         * create a ui button , tool bar button use this button.
         * @param name String
         * the icon name it will load the icon by name.
         * @param fun function
         * the fun will be call when the button was pressed.
         * @return sap.ui.conmmons.Button
         */
        _createCommonButton: function(name, fun) {
            var that = this;
            var icon = "sap-icon://" + name;
            return new sap.ui.commons.Button({
                icon: icon,
                enabled: false,
                press: function(oEvent) {
                    fun(oEvent, that);
                }
            });
        },

        /***
         * this function is called when the row is selected.
         * it will change the data when a row is selected. 
         * @param oEvent
         * information of this event.
         * @param that
         * the object of this control   
         */
        _selectedItem: function(oEvent, that) {
            var rowIndex = oEvent.getParameters().rowIndex;
            var rowIndices = oEvent.getParameters().rowIndices;
            var data = this.getModel().getData();
            var items = data['data'];
            if (rowIndex === -1 || rowIndices.length === items.length) {
                var selected = false;
                if (rowIndex === 0) {
                    selected = true;
                }
                for (var i = 0; i < items.length; i++) {
                    items[i].selected = selected;
                }
            } else {
                for (var i = 0; i < rowIndices.length; i++) {

                    items[rowIndices[i]].selected = !items[rowIndices[i]].selected;

                }
            }

            this._enabledToolbarButton(false);

            for (var i = 0; i < items.length; i++) {
                if (items[i].selected === true) {
                    this._enabledToolbarButton(true);
                    return;
                }
            }

        },
        
        /***
         * to send email to user when the email button is pressed , has not finish
         * @param oEvent
         * information of this event.
         * @param that
         * the object of this control 
         */
        _sendEmail: function(oEvent, that) {
            var id = oEvent.getParameters().id;
            var index = id[id.length - 1];
            sap.m.MessageToast.show("send a email to " + index + " to reset the password");
        },

        /***
         * when the add button is pressed , it will add a new user in the top.
         * @param oEvent
         * information of this event.
         * @param that
         * the object of this control 
         */
        _addUser: function(oEvent, that) {
            var date = new Date();
            var month = date.getMonth() + 1;
            var day = date.getDate();
            if (month < 10) {
                month = "0" + month;
            }
            if (day < 10) {
                day = "0" + day;
            }
            var validFrom = month + "/" + day + "/" + date.getFullYear();
            var data = that.getModel().getData();
            var items = data['data'];
            var user = {
                "id": -1,
                "role": "AppAdmin",
                "validFrom": validFrom,
                "validTo": "12/31/9999"
            };
            items.splice(0, 0, user);
            for (var i = 0; i < items.length; i++) {
                items[i].selected = false;
            }
            that.getModel().setData(data);
            that.clearSelection();
            that._enabledToolbarButton(false);
        },

        /***
         * when the less button is pressed , it will delete the users which been selected.
         * @param oEvent
         * information of this event.
         * @param that
         * the object of this control 
         */
        _lessUser: function(oEvent, that) {
            var data = that.getModel().getData();
            var items = data['data'];
            for (var i = items.length - 1; i >= 0; i--) {
                if (items[i].selected === true) {
                    items.splice(i, 1);
                }
            }
            that.getModel().setData(data);
            that.clearSelection();
            that._enabledToolbarButton(false);
        },

        /***
         * when the lock button is pressed , it will lock the users which been selected.
         * @param oEvent
         * information of this event.
         * @param that
         * the object of this control 
         */
        _lockUser: function(oEvent, that) {
            var data = that.getModel().getData();
            var items = data['data'];
            for (var i = 0; i < items.length; i++) {
                if (items[i].selected === true) {
                    items[i].status = "CLOSED";
                }
            }
            that.getModel().setData(data);
        },

        /***
         * when the unlock button is pressed , it will unlock users which been selected.
         * @param oEvent
         * information of this event.
         * @param that
         * the object of this control 
         */
        _unLockUser: function(oEvent, that) {
            var data = that.getModel().getData();
            var items = data["data"];
            for (var i = 0; i < items.length; i++) {
                if (items[i].selected === true) {
                    items[i].status = "OPEN";
                }
            }
            that.getModel().setData(data);
        },

        /***
         * this function for the role select control.
         * when the event is fired change the data.
         * @param oEvent
         * information of this event. 
         */
        _roleSelected: function(oEvent) {
            var item = oEvent.getParameters().selectedItem;
            var role = item.getKey();
            var id = oEvent.getSource().sId;
            var index = id[id.length - 1];
            var data = this.getModel().getData();
            item = data['data'][index];
            item.role = role;
            this.getModel().setData(data);
        },

        /***
         * hide or show the tool bar
         * @param bEnabled boolean
         * true: show the tool bar. false:hide the tool bar.
         */
        _enabledToolbarButton: function(bEnabled) {
            this._oLessButton.setEnabled(bEnabled);
            this._oLockedButton.setEnabled(bEnabled);
            this._oUnLockedButton.setEnabled(bEnabled);
        },

        renderer: "sap.ui.table.TableRenderer"

    });
});
